//
// Created by user on 20-4-9.
//
#include "Cpu.h"

inline void getCpuId(unsigned int mop, unsigned int sop, unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
                     unsigned int *edx) {

    __asm__ __volatile__    (
    "cpuid	\n\t"
    :"=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
    :"0"(mop), "2"(sop)
    );

}

void initCpu(void) {

    unsigned int i, j;
    unsigned int CpuFacName[4] = {0, 0, 0, 0};
    char FactoryName[17] = {0};

    // 1.获取到处理器支持的最大基础功能号
    getCpuId(0, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);

    *(unsigned int *) &FactoryName[0] = CpuFacName[1];

    *(unsigned int *) &FactoryName[4] = CpuFacName[3];

    *(unsigned int *) &FactoryName[8] = CpuFacName[2];

    FactoryName[12] = '\0';
    printfColor(YELLOW, BLACK, "%s  ", FactoryName);
    printfColor(YELLOW, BLACK, "%lx %lx %lx\n", CpuFacName[1], CpuFacName[3],
                CpuFacName[2]);

    //brand_string
    for (i = 0x80000002; i < 0x80000005; i++) {

        getCpuId(i, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);

        *(unsigned int *) &FactoryName[0] = CpuFacName[0];

        *(unsigned int *) &FactoryName[4] = CpuFacName[1];

        *(unsigned int *) &FactoryName[8] = CpuFacName[2];

        *(unsigned int *) &FactoryName[12] = CpuFacName[3];

        FactoryName[16] = '\0';

        printfColor(YELLOW, BLACK, "%s", FactoryName);

    }

    printfColor(YELLOW, BLACK, "\n");

    // 获取处理器的版本信息
    getCpuId(1, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);
    printfColor(YELLOW, BLACK,
                "Family Code: %lx, Extended Family : %lx, Model Number : %lx, Extended Model : %lx, Processor Type : %lx, Stepping ID : %lx\n",
                (CpuFacName[0] >> 8 & 0xf), (CpuFacName[0] >> 20 & 0xff), (CpuFacName[0] >> 4 & 0xf),
                (CpuFacName[0] >> 16 & 0xf), (CpuFacName[0] >> 12 & 0x3), (CpuFacName[0] & 0xf));

    // 获取线性/物理地址位宽
    getCpuId(0x80000008, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);
    printfColor(YELLOW, BLACK, "Physical Address size: %d, Linear Address size : %d\n", (CpuFacName[0] & 0xff),
                (CpuFacName[0] >> 8 & 0xff));

    // 获取到处理器支持的最大基础功能号
    getCpuId(0, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);
    printfColor(INDIGO, BLACK, "MAX Basic Operation Code : %lxs\n", CpuFacName[0]);

    // 获取处理器支持的最大扩展功能号
    getCpuId(0x80000000, 0, &CpuFacName[0], &CpuFacName[1], &CpuFacName[2], &CpuFacName[3]);
    printfColor(INDIGO, BLACK, "MAX Extended Operation Code : %lx\n", CpuFacName[0]);


}